import React from 'react';
import { observer, inject } from 'mobx-react';
import { Row, Col, Icon, Modal, message } from 'antd';
import { WeaSelect, WeaInput, WeaTools, WeaTableEditable, WeaLocaleProvider, WeaError, WeaHelpfulTip } from 'ecCom';
import { getView } from '../../form/component';
import { isWrapper, isOptional, canSetFieldVal } from '../../form/component/typeof';
import { toJS } from 'mobx';
import _ from 'lodash';
import querystring from 'querystring';
import utils from '../../../../utils';
import { comsType } from '../../../../constants/form';

const confirm = Modal.confirm;
const edcField = 'edc_field';
const LanguageId = 'languageId';
const getLabel = WeaLocaleProvider.getLabel;
const baseUrl = `${location.protocol}//${location.host}`;

@inject('edcSettingDesignerStore')
@observer
export default class AddFiledVal extends React.Component {
    constructor(props) {
        super(props);

        const allComs = this.getAllComs(toJS(props.coms));
        this.coms = allComs.filter(com => canSetFieldVal(com)).filter(com => com.fieldName);
        this.store = props.edcSettingDesignerStore;

        const { changeAddFieldsUrl } = this.store;
        const fieldsOpts = this.coms.map((com) => {
            let key = com.detailTable ? `${com.detailTable}.${com.fieldName}` : com.fieldName;

            return { showname: com.config.title, key };
        });

        this.state = {
            languageOpts: [],
            fields: [],
            extendValue: '',
            languageId: '',
            fieldsOpts: fieldsOpts || [],
        };

        changeAddFieldsUrl(props.url);
    }

    componentDidMount() {
        WeaTools.callApi(
            '/api/system/language/base/getActiveLanguage',
            'GET',
        ).then((res) => {
            if (res.activeLanguageInfo) {
                const languageOpts = res.activeLanguageInfo.map(r => ({
                        key: r.id,
                        showname: r.language,
                    }));

                languageOpts.unshift({ key: '', showname: '' });

                this.setState({ languageOpts });
            }
        });
        this.setFields(this.props.url);
    }

    setFields = (url) => {
        const params = querystring.parse(url.split('?')[1]);
        const fields = [];

        for (let key in params) {
            const isFieldParam = !!~this.coms.findIndex((com) => {
                if (com.detailTable) {
                    return `${com.detailTable}.${com.fieldName}` === key;
                }

                return com.fieldName === key;
            }) || (key === edcField && params[key]);

            if (key === LanguageId) this.setState({ languageId: params[key] });

            if (isFieldParam) {
                fields.push({ fieldName: key, value: params[key], id: utils.UUID() });
            }
        }

        this.setState({ fields });
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.visible !== this.props.visible && nextProps.visible) {
            this.setFields(nextProps.url);
        }
    }

    getAllComs = (coms) => {
        const allComs = [];

        if (coms) {
            coms.map((com) => {
                if (isWrapper(com)) {
                    com.config.coms.forEach((com) => {
                        com && allComs.push(com);
                    });
                } else {
                    allComs.push(com);
                }
            });
        }

        return allComs;
    }

    getCom = (fieldName) => {
        const fieldInfo = fieldName ? fieldName.split('.') : '';
        let detailTable = '';

        if (fieldInfo.length === 2) {
            detailTable = fieldInfo[0];
            fieldName = fieldInfo[1];
        } else {
            fieldName = fieldInfo[0];
        }

        const com = this.coms.find((com) => {
            if (detailTable) {
                return com.fieldName === fieldName && com.detailTable === detailTable;
            }

            return com.fieldName === fieldName;
        });

        return com;
    }

    getFieldCom = (fieldName, value, id) => {
       const com = this.getCom(fieldName);

        if (fieldName === edcField) {
            return <WeaInput ecId={`${this && this.props && this.props.ecId || ''}_WeaInput@5d2pgm`} value={value} onChange={value => this.onValChange(fieldName, value, id)} />;
        }

        if (!com) return null;
        if (isOptional(com)) {
            value = this.formatSelectVal(com, value.split(','));
        }

        const ComponentView = getView(com.type);
        const data = { ...com.config, disableTitle: true };
        let errorMsg = '';

        if (com.type === comsType.EMAIL) {
            errorMsg = getLabel('510153', '请输入正确的邮箱地址,格式为xxx@xx.xx');
        } else if (com.type === comsType.MOBILE) {
            errorMsg = getLabel('510152', '请输入长度为11位的手机号');
        }

        return (
            <WeaError ecId={`${this && this.props && this.props.ecId || ''}_WeaError@0bi5ae`}
              error={errorMsg}
              tipPosition="bottom"
              ref={error => this[id] = error}
            >
                <ComponentView ecId={`${this && this.props && this.props.ecId || ''}_ComponentView@2vrkue`}
                  type={com.type}
                  value={value}
                  uuid={com.uuid}
                  data={data}
                  onChange={(value) => {
                        com.value = value;

                        if (isOptional(com)) {
                            const vals = value.map(val => val.key);
                            const { options } = com.config;
                            const optVals = [];

                            vals.forEach((val) => {
                                const selectedOpt = options.find(opt => opt.key === val);

                                optVals.push(selectedOpt.showname);
                            });

                            value = optVals.join(',');
                        }

                        const field = com.detailTable ? `${com.detailTable}.${com.fieldName}` : com.fieldName;

                        this.onValChange(field, value, id);
                    }}
                />
            </WeaError>
        );
    }

    formatSelectVal = (com, value) => {
        const { options } = com.config;
        const vals = [];

        options.forEach(({ showname, key }) => {
            if (value && value.length > 0 && value.indexOf(showname) > -1) {
                vals.push({
                    key,
                    value: showname,
                });
            }
        });

        return vals;
    }

    onValChange = (fieldName, value, id) => {
        const com = this.getCom(fieldName);
        const { fields } = this.state;

        if (com && com.pid) { // 复杂组件赋值， 例如地址组件
            const { key: subComKey } = com;
            const perentCom = this.coms.find(item => item.uuid === com.pid);

            if (subComKey && perentCom) {
                perentCom.config[subComKey].config.defaultValue = value;
                perentCom.config[subComKey].value = value;
            }
        }

        const index = fields.findIndex(field => field.fieldName === fieldName);

        fields.splice(index, 1, { value, fieldName, id });
        this.setState({ fields }, () => {
            this.getNewLink();
        });
    }

    getNewLink = () => {
        const { fields, extendValue, languageId } = this.state;
        let { changeAddFieldsUrl } = this.store;
        let { url } = this.props;

        const fieldParams = {};

        fields.map((field) => {
            const { fieldName, value } = field;

            if (!value) return;

            fieldParams[fieldName] = value;
        });

        let params = {};

        if (extendValue) {
            params.edc_field = extendValue;
        } else if (languageId) {
            params.languageId = languageId;
        }

        params = { ...params, ...fieldParams };

        if (_.keys(params).length) {
            url = `${url.split('?')[0]}?${querystring.stringify(params, null, null, { encodeURIComponent: '' })}`;
        } else {
            url = url.split('?')[0];
        }

        changeAddFieldsUrl(url);
    }

    onLangChange = (languageId) => {
        this.setState({ languageId }, () => {
            this.getNewLink();
        });
    };

    onFieldTypeChange = (fieldName, index, id) => {
        const { fields } = this.state;
        const ind = fields.findIndex(field => field.fieldName === fieldName);

        if (ind > -1) {
            message.warning(getLabel(522057, '该字段已经赋值'));
            Object.assign(fields[index], { id: utils.UUID() });
            fields.splice(index, 1, fields[index]);
            this.setState({ fields });
        } else {
            fields.splice(index, 1, { fieldName, value: '', id });
            this.setState({ fields }, () => {
                this.getNewLink();
            });
        }
    }

    addField = () => {
        const { fields } = this.state;

        fields.push({ fieldName: '', value: '', id: utils.UUID() });
        this.setState({ fields }, () => {
            this.getNewLink();
        });
    }

    deleteData = (datas, keys) => {
        let { fields } = this.state;

        confirm({
            title: getLabel(522058, '您是否确认要删除选中的字段'),
            onOk: () => {
                fields = fields.filter(field => !~keys.indexOf(field.id));

                this.setState({ fields }, () => {
                    this.getNewLink();
                });
            },
            onCancel() { },
        });
    }

    render() {
        const { fieldsOpts, languageOpts, fields, languageId } = this.state;
        const { url } = this.props;

        return (
            <div className="wea-edc-setting-add-field-val">
                <Row ecId={`${this && this.props && this.props.ecId || ''}_Row@ztag6d`}>
                    <Col ecId={`${this && this.props && this.props.ecId || ''}_Col@yzq3k8`} span={3} title={getLabel(522054, '访问地址')}>{getLabel(522054, '访问地址')}：</Col>
                    <Col ecId={`${this && this.props && this.props.ecId || ''}_Col@hut449`} span={21} title={`${baseUrl}${url}`} className="url">
                        <WeaInput ecId={`${this && this.props && this.props.ecId || ''}_WeaInput@ezobvo`} value={`${baseUrl}${url}`} viewAttr="1" hasBorder={true} />
                    </Col>
                </Row>
                <Row ecId={`${this && this.props && this.props.ecId || ''}_Row@y960z4`}>
                    <Col ecId={`${this && this.props && this.props.ecId || ''}_Col@ailjgo`} span={3} title={getLabel(523865, '语言')}>{getLabel(523865, '语言')}：</Col>
                    <Col ecId={`${this && this.props && this.props.ecId || ''}_Col@4c6j29`} span={21}>
                        <WeaSelect ecId={`${this && this.props && this.props.ecId || ''}_WeaSelect@7i2o5e`}
                          showSearch
                          optionFilterProp="children"
                          options={languageOpts}
                          value={languageId}
                          onChange={this.onLangChange}
                        />
                    </Col>
                </Row>
                <div className="wea-edc-fields">
                    <WeaTableEditable ecId={`${this && this.props && this.props.ecId || ''}_WeaTableEditable@hm0wqm`}
                      title={
                            <span>
                                {getLabel(522059, '字段赋值')}
                                <WeaHelpfulTip ecId={`${this && this.props && this.props.ecId || ''}_WeaHelpfulTip@rr8tbc`}
                                  title={getLabel(523867, '设置的字段越多，会导致二维码清晰度降低，在扫码时出现无法扫描的情况，请谨慎设置!')}
                                  placement="top"
                                />
                            </span>
                        }
                      columns={[
                            {
                                title: getLabel('512079', '选择字段'),
                                dataIndex: 'fieldName',
                                width: 170,
                                com: [{
                                    type: 'CUSTOM',
                                    render: (text, record, index) => {
                                        if (text === edcField) {
                                            return <span>{getLabel(522060, '扩展字段')}</span>;
                                        }
                                        return (
                                            <WeaSelect ecId={`${this && this.props && this.props.ecId || ''}_WeaSelect@cm14gj@${index}`}
                                              showSearch
                                              optionFilterProp="children"
                                              options={fieldsOpts}
                                              value={text}
                                              onChange={value => this.onFieldTypeChange(value, index, record.id)}
                                            />
                                        );
                                    },
                                }],
                            }, {
                                title: getLabel(522061, '字段值'),
                                dataIndex: 'value',
                                width: 240,
                                com: [{
                                    type: 'CUSTOM',
                                    render: (text, record) => this.getFieldCom(record.fieldName, text, record.id),
                                }],
                            }, {
                                title: getLabel(522062, '操作'),
                                dataIndex: 'opt',
                                com: [{
                                    type: 'CUSTOM',
                                    render: (text, record) => <span className="delete-data" onClick={() => this.deleteData(record.url, [record.id])}><Icon ecId={`${this && this.props && this.props.ecId || ''}_Icon@c1fsmg@`} type="delete" /></span>,
                                }],
                            },
                        ]}
                      datas={fields}
                      showCopy={false}
                      willAdd={this.addField}
                      willDelete={this.deleteData}
                      tableProps={{ scroll: { y: true } }}
                    />
                </div>
            </div>
        );
    }
}
